package com.rjkj.medicalwaste.viewmodels

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.inuker.bluetooth.library.Constants.REQUEST_SUCCESS
import com.inuker.bluetooth.library.connect.response.BleWriteResponse
import com.rjkj.medicalwaste.base.BaseViewModel
import com.rjkj.medicalwaste.bean.*
import com.rjkj.medicalwaste.bluetooth.BluetoothState
import com.rjkj.medicalwaste.ui.setting.PrintItem
import com.rjkj.medicalwaste.utils.*
import kotlinx.coroutines.*
import java.util.*


class BluetoothControlViewModel : BaseViewModel() {
    val decoder04Bean = MutableLiveData(Decoder04Bean())
    val decoder03Bean = MutableLiveData(Decoder03Bean())
    val bluetoothSwitch = MutableLiveData(false)
    val bluetoothTry = MutableLiveData<BlueConnectResult>()
    var bluetoothType = 0//0未连接 1传统蓝牙 2低功耗蓝牙
    var mac = ""
    var launch: Job? = null
    private val btSPP = BlueManager.instance.blue

    data class PrintGarbage(var type: String, var weight: Double)

    fun printRecTest(encode03IF: Encode03IF) {
        viewModelScope.launch(Dispatchers.IO) {
            val data = SerializeUtil.byteArrayToHexString(encode03IF.pirntMessage)
            BlueDeviceHelper.sendPrintDataMessage(btSPP, data)
        }
    }


    fun printOutPaper(
        garbageBean: List<WaitHandoverGarbageBean>,
        userBeen: UserBean,
        disposalUser: UserBean,
        list: List<PrintItem>,
    ) {

        val entries = garbageBean.groupBy { it.garbageBoxType }.map {
            PrintGarbage(it.key, it.value.sumByDouble { garbageBean ->
                garbageBean.garbageBoxWeight
            })
        }
        dealHandoverForm(
            "",
            userBeen.name,
            disposalUser.name,
            TimeUtils.getYMDHMSTime(),
            entries,
            list
        )

    }


    /*发送打印箱标签指令*/
    fun packingBoxTag(encode03IF: Encode03IF) {
        val data = SerializeUtil.byteArrayToHexString(encode03IF.pirntMessage)
        BlueDeviceHelper.sendPrintDataMessage(btSPP, data)
    }

    //打印袋码
    fun printRec(encode03IF: Encode03IF) {
        val data = SerializeUtil.byteArrayToHexString(encode03IF.pirntMessage)
        BlueDeviceHelper.sendPrintDataMessage(btSPP, data)
    }

    //打印交接单
    fun printHandoverInfo(
        cleaner: UserBean,
        department: UserBean,
        nurse: UserBean,
        list: List<GarbageBean>,
        itemList: List<PrintItem>
    ): Boolean {
        val entries = list.groupBy { it.garbageType }.map {
            PrintGarbage(it.key, it.value.sumByDouble { garbageBean ->
                garbageBean.garbageWeight.toDouble()
            })
        }
        dealHandoverForm(
            cleaner.name,
            department.name,
            nurse.name,
            TimeUtils.getYMDHMSTime(),
            entries,
            itemList
        )
        return true
    }

    //处理打印的策略
    private fun dealHandoverForm(
        department: String,
        cleaner: String,
        nurse: String,
        timestamp: String,
        list: List<PrintGarbage>,
        itemList: List<PrintItem>
    ) {
//        val weightTotal =
//            DecimalFormat("0.00").format(type_weight1 + type_weight2 + type_weight5 + type_weight6 + type_weight7 + type_weight3 + type_weight8) //保留二位小数
        if (list.size >= 7) {
            list.filter { itemList.contains(PrintItem(type = it.type)) }
        }
        val templete = "1A5B01000000008001F00000info1A5D001A4F00"
        val hexStr = setPrintInfo2(
            department,
            cleaner,
            nurse,
            timestamp,
            list
        ).let { templete.replace("info", it) }
        val headerbytes = byteArrayOf(
            0x01,
            0x01,
            0x1A,
            0x5B,
            0x01,
            0x00,
            0x00,
            0x00,
            0x00,
            0x80.toByte(),
            0x01,
            0xF0.toByte(),
            0x00,
            0x00
        )
        val endbytes = byteArrayOf(0x1A, 0x5D, 0x00, 0x1A, 0x4F, 0x00, 0x1B, 0x69)
        val infobytes = SerializeUtil.hexStringToByteArray(hexStr)
        val printbytes: ByteArray = combineArrays(headerbytes, infobytes, endbytes)
        BlueDeviceHelper.sendHanMessage(btSPP, getPirntMessage(printbytes))
    }


    private fun getPirntMessage(printbytes: ByteArray): ByteArray {
        val length = printbytes.size
        val headerbytes =
            byteArrayOf(0xaa.toByte(), 0x55, 0x03, (length / 256).toByte(), (length % 256).toByte())
        var sum = 0
        val temp = combineArrays(headerbytes, printbytes)
        for (b in temp) {
            sum += b.toInt()
        }
        val endbytes = byteArrayOf((sum % 256).toByte(), 0xbb.toByte(), 0x66)
        return combineArrays(temp, endbytes)
    }

    private fun combineArrays(vararg info: ByteArray): ByteArray {
        var length = 0
        for (arr in info) {
            length += arr.size
        }
        val result = ByteArray(length)
        var index = 0
        for (str in info) {
            System.arraycopy(str, 0, result, index, str.size)
            index += str.size
        }
        return result
    }

    fun printOnce() {
        BlueDeviceHelper.sendRealTimeDataMessage(btSPP, "AA550403BB66")
    }

    fun startRec() {
        launch = viewModelScope.launch {
            withContext(Dispatchers.Default) {
                // 繁重任务
                while (isActive && bluetoothType == 1) {
                    Log.e("Observable", "====")
                    BlueDeviceHelper.sendRealTimeDataMessage(btSPP, "AA550403BB66")
                    delay(250L)
                }

            }

        }
    }

    fun zeroRec() {
        if (bluetoothType == 1) {
            BlueDeviceHelper.sendRealTimeDataMessage(btSPP, "AA558100000106BB66")
        } else if (bluetoothType == 2) {
            val UUID_SERVER = "0000ffe0-0000-1000-8000-00805f9b34fb"
            val UUID_STRING = "0000ffe1-0000-1000-8000-00805f9b34fb"
            ClientManager.client?.write(
                mac,
                UUID.fromString(UUID_SERVER),
                UUID.fromString(UUID_STRING),
                HexUtil.hexStr2Bytes("1B0D0A")
            ) { code ->
                if (code == REQUEST_SUCCESS) {
                }
            }

        }
    }


    fun stopRec() {
        if (launch != null) {
            launch!!.cancel()
        }

        decoder04Bean.value = Decoder04Bean()
    }

    fun bluetoothSendData(data: ByteArray): Boolean {
        if (btSPP.serviceState == BluetoothState.STATE_CONNECTED) {
            btSPP.send(data, false)

            return true
        }
        return false
    }

    /**
     * 大号标签打印
     * @param hospital String
     * @param department String
     * @param cleaner String
     * @param nurse String
     * @param timestamp String
     * @param weight1 String
     * @param weight2 String
     * @param weight3 String
     * @param weight4 String
     * @param weight5 String
     * @param weight6 String
     * @param weight8 String
     * @param weightTotal String
     * @return String
     */
    fun setPrintInfo(
        hospital: String,
        department: String,
        cleaner: String,
        nurse: String,
        timestamp: String,
        weight1: String,
        weight2: String,
        weight3: String,
        weight4: String,
        weight5: String,
        weight6: String,
        weight8: String,
        weightTotal: String
    ): String {
        val templete = "1A5400xxxxyyyyzzzz00"
        try {
            var X_ = ""
            X_ = if (hospital.length > 8) {
                "5"
            } else {
                "9"
            }
            //医院
            val printHospital = templete.replace("xxxxyyyy", X_ + "0000800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(hospital.toByteArray(charset("gb2312")))
                )
            //title
            val title = templete.replace("xxxxyyyy", "50002800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("医疗废物(周转)交接单".toByteArray(charset("gb2312")))
                )
            val line1 = templete.replace("xxxxyyyy", "00004800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        " -----------------------------".toByteArray(charset("gb2312"))
                    )
                )
            //科室
            val printDepartment = templete.replace("xxxxyyyy", "00006800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("科室:$department".toByteArray(charset("gb2312")))
                )
            //清理工--收集人
            val printCleaner = templete.replace("xxxxyyyy", "00008800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("周转人:$cleaner".toByteArray(charset("gb2312")))
                )
            //护士--确认人
            val printNurse = templete.replace("xxxxyyyy", "0000A800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("交接人:$nurse".toByteArray(charset("gb2312")))
                )
            //日期 格式：18-12-07 14:02:56
            val printTimestamp = templete.replace("xxxxyyyy", "0000C800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("时间:" + timestamp.substring(
                            2,
                            10
                        ) + "     " + timestamp.substring(11)).toByteArray(charset("gb2312"))
                    )
                )
            val line2 = templete.replace("xxxxyyyy", "0000E800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        " -----------------------------".toByteArray(charset("gb2312"))
                    )
                )
            val type4 = templete.replace("xxxxyyyy", "B0000601")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("病理性:" + weight4 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type5 = templete.replace("xxxxyyyy", "B0002401")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("药物性:" + weight5 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type6 = templete.replace("xxxxyyyy", "B0004201")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("可回收:" + weight6 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type1 = templete.replace("xxxxyyyy", "00000601")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("感染性:" + weight1 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type2 = templete.replace("xxxxyyyy", "00002401")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("损伤性:" + weight2 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type3 = templete.replace("xxxxyyyy", "00004201")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("化学性:" + weight3 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val type8 = templete.replace("xxxxyyyy", "00006001")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("新冠:" + weight8 + "kg").toByteArray(
                            charset("gb2312")
                        )
                    )
                )
            val typeTotal = templete.replace("xxxxyyyy", "B0006001")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("合计:" + weightTotal + "kg").toByteArray(charset("gb2312"))
                    )
                )
            val line3 = templete.replace("xxxxyyyy", "00007E01")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        " -----------------------------".toByteArray(charset("gb2312"))
                    )
                )
            val name1 = templete.replace("xxxxyyyy", "00009C01")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("交接人:".toByteArray(charset("gb2312")))
                )
            val name2 = templete.replace("xxxxyyyy", "B0009C01")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("周转人:".toByteArray(charset("gb2312")))
                )
            return printHospital + title + line1 + printDepartment + printCleaner + printNurse + printTimestamp + line2 + type1 + type4 + type2 + type5 + type3 + type6 + type8 + typeTotal + line3 + name1 + name2
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return ""
    }

    /**
     * 小号标签打印
     * @param hospital String?
     * @param department String
     * @param cleaner String
     * @param nurse String
     * @param timestamp String
     * @param weight1 String
     * @param weight2 String
     * @param weight3 String
     * @param weight4 String
     * @param weight5 String
     * @param weight6 String
     * @param weight7 String
     * @param weightTotal String
     * @return String
     */
    fun setPrintInfo2(
        department: String,
        cleaner: String,
        nurse: String,
        timestamp: String,
        list: List<PrintGarbage>
    ): String {
        val templete = "1A5400xxxxyyyyzzzz00"
        try {
            //清理工--收集人
            val printCleaner = templete.replace("xxxxyyyy", "00000800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("周转人:$cleaner".toByteArray(charset("gb2312")))
                )
            //护士--确认人
            val printNurse = templete.replace("xxxxyyyy", "B0000800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString("交接人:$nurse".toByteArray(charset("gb2312")))
                )
            //日期 格式：18-12-07 14:02:56
            val printTimestamp = templete.replace("xxxxyyyy", "00002800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        (department + ":" + timestamp.substring(2)).toByteArray(charset("gb2312"))
                    )
                )
            val weightTotal = list.sumByDouble {
                it.weight
            }
            val typeTotal = templete.replace("xxxxyyyy", "B000A800")
                .replace(
                    "zzzz",
                    SerializeUtil.byteArrayToHexString(
                        ("合计:" + weightTotal + "kg").toByteArray(charset("gb2312"))
                    )
                )
            val strList = list.map {
                templete.replace("xxxxyyyy", "0000A800")
                    .replace(
                        "zzzz",
                        SerializeUtil.byteArrayToHexString(
                            ("${it.type}:${it.weight}kg").toByteArray(
                                charset("gb2312")
                            )
                        )
                    )
            }
            var result = printCleaner + printNurse + printTimestamp
            for (value in strList) {
                result += value
            }
            result += typeTotal
            return result

        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return ""
    }


//    /**
//     * 小号标签打印
//     * @param hospital String?
//     * @param department String
//     * @param cleaner String
//     * @param nurse String
//     * @param timestamp String
//     * @param weight1 String
//     * @param weight2 String
//     * @param weight3 String
//     * @param weight4 String
//     * @param weight5 String
//     * @param weight6 String
//     * @param weight7 String
//     * @param weightTotal String
//     * @return String
//     */
//    fun setPrintInfo2(
//        hospital: String?,
//        department: String,
//        cleaner: String,
//        nurse: String,
//        timestamp: String,
//        weight1: String,
//        weight2: String,
//        weight3: String,
//        weight4: String,
//        weight5: String,
//        weight6: String,
//        weight7: String,
//        weightTotal: String
//    ): String {
//        val templete = "1A5400xxxxyyyyzzzz00"
//        try {
//            //清理工--收集人
//            val printCleaner = templete.replace("xxxxyyyy", "00000800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString("周转人:$cleaner".toByteArray(charset("gb2312")))
//                )
//            //护士--确认人
//            val printNurse = templete.replace("xxxxyyyy", "B0000800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString("交接人:$nurse".toByteArray(charset("gb2312")))
//                )
//            //日期 格式：18-12-07 14:02:56
//            val printTimestamp = templete.replace("xxxxyyyy", "00002800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        (department + ":" + timestamp.substring(2)).toByteArray(charset("gb2312"))
//                    )
//                )
//            val type1 = templete.replace("xxxxyyyy", "00004800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("感染性:" + weight1 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type2 = templete.replace("xxxxyyyy", "00006800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("损伤性:" + weight2 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type3 = templete.replace("xxxxyyyy", "00008800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("病理性:" + weight3 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type4 = templete.replace("xxxxyyyy", "B0004800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("药物性:" + weight4 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type5 = templete.replace("xxxxyyyy", "B0006800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("化学性:" + weight5 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type6 = templete.replace("xxxxyyyy", "B0008800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("胎盘:" + weight6 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//
//            val type8 = templete.replace("xxxxyyyy", "0000A800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("利器盒:" + weight7 + "kg").toByteArray(
//                            charset("gb2312")
//                        )
//                    )
//                )
//            val typeTotal = templete.replace("xxxxyyyy", "B000A800")
//                .replace(
//                    "zzzz",
//                    SerializeUtil.byteArrayToHexString(
//                        ("合计:" + weightTotal + "kg").toByteArray(charset("gb2312"))
//                    )
//                )
//            return printCleaner + printNurse + printTimestamp + type1 + type4 + type2 + type5 + type3 + type6 + type8 + typeTotal
//        } catch (e: java.lang.Exception) {
//            e.printStackTrace()
//        }
//        return ""
//    }
}